/*********************
* Author:Dzlua
* QQ:505544956
* time:2016/06/27
*/
#ifndef __EDUI_MGR_H__
#define __EDUI_MGR_H__

#include "../defines.h"
#include "../utilities/Log.h"

#include <vector>
#include <string.h>

EDUI_NAMESPACE_BEGIN

template<class T>
class MgrSimple
{
public:
    MgrSimple()
    {
        m_map = new DataMap;
        Assert(m_map);
    }

    ~MgrSimple()
    {
        if (m_map){
            delete m_map;
            m_map = 0;
        }
    }

public:
    void Add(T* data)
    {
        m_map->push_back(data);
    }

    void AddAt(T* data, int index)
    {
        if (index < 0) index = 0;
        m_map->insert(m_map->begin() + index, data);
    }

    T* GetByIndex(size_t index)
    {
        if (index < 0 || index >= m_map->size()) return 0;
        return m_map->at(index);
    }

    void Remove(T* data)
    {
        if (!data) return;
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && (*it) == data){
                m_map->erase(it);
                return;
            }
        }
    }

    void Clear()
    {
        m_map->clear();
    }
    
    size_t Count()
    {
        return m_map->size();
    }
    
private:
    typedef std::vector<T*> DataMap;
    DataMap* m_map;
};

template<class T>
class Mgr
{
public:
	Mgr() : m_map(0)
    {
        m_map = new DataMap;
        Assert(m_map);
    }

	~Mgr()
    {
        this->Clear();
        if (m_map){
            delete m_map;
            m_map = 0;
        }
    }

    bool Add(const char* name, T* data, int id = -1)
    {
        if (!data || !name) return false;
        if (id < -1) id = -1;
        if (this->Get(name)) return false;
        if (this->GetName(data)) return false;
        if (id != -1 && this->Get(id)) return false;
        sData* sdata = new sData(name, data, id);
        if (!sdata) return false;
        Assert(sdata);
        if (!sdata->IsOK()){
            delete sdata;
            sdata = 0;
            return false;
        }

        m_map->push_back(sdata);
        return true;
    }

    const char* GetName(T* data)
    {
        if (!data) return 0;
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && (*it)->data == data){
                return (*it)->name;
            }
        }
        return 0;
    }

    int GetId(T* data)
    {
        if (!data) return -1;
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && (*it)->data == data){
                return (*it)->id;
            }
        }
        return -1;
    }

    T* Get(const char* name)
    {
        if (!name) return 0;
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && strcmp((*it)->name, name) == 0){
                return (*it)->data;
            }
        }
        return 0;
    }

    T* Get(int id)
    {
        if (id < 0) return 0;
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && (*it)->id == id){
                return (*it)->data;
            }
        }
        return 0;
    }

    T* GetByIndex(size_t index)
    {
        if (index >= m_map->size()) return 0;
        sData* sdata = m_map->at(index);
        if (!sdata) return 0;
        return sdata->data;
    }

    size_t Count()
    {
        return m_map->size();
    }

    void Remove(const char* name)
    {
        if (!name) return;
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && strcmp((*it)->name, name) == 0){
                delete (*it);
                (*it) = 0;
                m_map->erase(it);
                return;
            }
        }
    }

    void Remove(int id)
    {
        if (id < 0) return;
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && (*it)->id == id){
                delete (*it);
                (*it) = 0;
                m_map->erase(it);
                return;
            }
        }
    }

    void Remove(T* data)
    {
        if (!data) return;
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && (*it)->data == data){
                delete (*it);
                (*it) = 0;
                m_map->erase(it);
                return;
            }
        }
    }

    void Clear()
    {
        typename DataMap::iterator it;
        for (it = m_map->begin(); it != m_map->end(); ++it){
            if(*it){
                delete (*it);
                (*it) = 0;
            }
        }
        m_map->clear();
    }
private:
    struct sData
    {
        T* data;
        int id;
        char* name;
        sData(const char* _name, T* _data, int _id) : data(0), id(-1), name(0)
        {
            if (!_name || !_data) return;
            name = new char[strlen(_name) + 1];
            if (!name) return;
            strcpy(name, _name);
            data = _data;
            id = _id;
        }
        ~sData()
        {
            if (name){
                delete name;
                name = 0;
            }
        }
        bool IsOK()
        {
            return (name != 0) && (data != 0);
        }
    };
	typedef std::vector<sData*> DataMap;
    DataMap* m_map;
};

EDUI_NAMESPACE_END

#endif